
#include <iostream>
#include <string>
using namespace std;

#include "Logger.hpp"

namespace tulun
{
    // Logger::
    // tulun::LogMessage impl_;

    void defaultOutput(const std::string &msg)
    {
        size_t n = fwrite(msg.c_str(), sizeof(char), msg.size(), stdout);
    }
    void defaultFlush()
    {
        fflush(stdout);
    }

    void Logger::setOutput(OutputFun fun)
    {
        s_output_ = fun;
    }
    void Logger::setFlush(FlushFun fun)
    {
        s_flush_ = fun;
    }

    Logger::OutputFun Logger::s_output_ = defaultOutput;
    Logger::FlushFun Logger::s_flush_ = defaultFlush;

    Logger::Logger(const tulun::LOG_LEVEL &level,
                   const string &filename,
                   const string &funcname,
                   const int line)
        : impl_(level, filename, funcname, line)
    {
    }
    Logger::~Logger()
    {
        impl_ << "\n";
        s_output_(impl_.toString());
        s_flush_();
        if (impl_.getLogLevel() == tulun::LOG_LEVEL::FATAL ||
            impl_.getLogLevel() == tulun::LOG_LEVEL::SYSFATAL)
        {
            fprintf(stderr, "process exit \n");
            exit(EXIT_FAILURE);
        }
    }
    tulun::LogMessage &Logger::stream()
    {
        return impl_;
    }
    tulun::LOG_LEVEL InitLogLevel()
    {
        if (::getenv("TULUN::LOG_TRACE"))
        {
            return tulun::LOG_LEVEL::TRACE;
        }
        else if (::getenv("TULUN::LOG_DEBUG"))
        {
            return tulun::LOG_LEVEL::DEBUG;
        }
        else
        {
            return tulun::LOG_LEVEL::INFO;
        }
    }
    tulun::LOG_LEVEL Logger::s_level_ = InitLogLevel();

    tulun::LOG_LEVEL Logger::getLogLevel()
    {
        return s_level_;
    }
    void Logger::setLogLevel(const tulun::LOG_LEVEL &level)
    {
        s_level_ = level;
    }

} // namespace tulun
